﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Media;
using Styx;
using Styx.Helpers;
using Styx.Common;
using Styx.Common.Helpers;
using Styx.CommonBot.POI;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;

namespace Lockery
{
    public partial class Classname : CombatRoutine
    {
        public string LastSpell = "";
        public string LastLog = "";

        public string ShadowBolt = "Shadow Bolt";
        public string Corruption = "Corruption";
        public string DrainLife = "Drain Life";
        public string CreateHealthStone = "Create Healthstone";
        public string Conflagrate = "Conflagrate";
        public string Incinerate = "Incinerate";
        public string HealthFunnel = "Health Funnel";
        public string Immolate = "Immolate";
        public string Fear = "Fear";
        public string CurseOfEnfeeblement = "Curse of Enfeeblement";
        public string Soulstone = "Soulstone";
        public string RainOfFire = "Rain of Fire";
        public string FireAndBrimbstone = "Fire and Brimstone";
        public string Havoc = "Havoc";
        public string UnendingBreath = "Unending Breath";
        public string MortalCoil = "Mortal Coil";
        public string TwilightWard = "Twilight Ward";
        public string ChaosBolt = "Chaos Bolt";
        public string EmberTap = "Ember Tap";
        public string ShadowBurn = "Shadowburn";
        public string DarkBargain = "Dark Bargain";
        public string SummonInfernal = "Summon Infernal";
        public string CurseOfTheElements = "Curse of the Elements";
        public string SummonDoomguard = "Summon Doomguard";
        public int DarkSoul = 113858;
        public int DarkIntent = 109773;
        public int SoulStone = 20707;
        public int GrimoireOfSacrifice = 108503;

        public bool RestNeeded()
        {
            if (Me.CurrentTarget == null
                && !Me.Mounted
                && !Me.IsFlying
                && Me.HasAura("Drink")
                || Me.HasAura("Food")
                || Me.HasAura("First Aid"))
            {
                return true;
            }
            return false;
        }

        #region usespells or not
        public bool UseSpells
        {
            get
            {
                if (Me.Mounted
                    || Me.IsGhost
                    || Me.IsDead)
                {
                    return false;
                }
                return true;
            }
        }
        #endregion usespells or not

        public string PullSpell
        {
            get
            {
                return null;
            }
        }

        public void CastSpell(string spell, int logColor)
        {
            if (Me.CurrentTarget != null
                && SpellManager.CanCast(spell)
                && !Me.Mounted)
            {
                SpellManager.Cast(spell);
                if (logColor == 7)
                {
                    LogMsg(spell + " multidot", logColor);
                }
                else
                {
                    LogMsg(spell, logColor);
                }
                LastSpell = spell;

            }

        }
        public void CastBuff(string spell, int logColor)
        {
            if (SpellManager.CanCast(spell)
            && !Me.HasAura(spell)
            && !Me.Mounted)
            {
                SpellManager.Cast(spell, StyxWoW.Me);
                LogMsg(spell, logColor);
                LastSpell = spell;
            }

        }
        public bool UseSkill(string spell)
        {
            if (Me.CurrentTarget != null
                && SpellManager.HasSpell(spell)
                && IsInRange(Me.CurrentTarget, 39)
                && !Me.IsChanneling)
            {
                if (!Me.CurrentTarget.InLineOfSight
                    && !LockerySettings.myPrefs.DisableMovement)
                {
                    MoveToLineOfSight();
                }
                return true;
            }
            return false;
        }
        public bool NeedAoeRotation
        {
            get
            {
                if (IsBoss)
                {
                    return false;
                }
                else if (addCount >= LockerySettings.myPrefs.UseAoe
                    && LockerySettings.myPrefs.NoAoeSolo
                    && MeSolo)
                {
                    return false;
                }
                else if (addCount >= LockerySettings.myPrefs.UseAoe)
                {
                    return true;
                }
                return false;
            }
        }
        #region groupinfo
        public bool MeInParty
        {
            get
            {
                if (Me.CurrentTarget != null)
                {
                    if (Me.GroupInfo.IsInRaid)
                    {
                        return true;
                    }
                    else if (Me.GroupInfo.IsInParty)
                    {
                        return true;
                    }
                    else if (Me.IsInInstance)
                    {
                        return true;
                    }
                }
                return false;
            }
        }
        public bool MeSolo
        {
            get
            {
                if (Me.CurrentTarget != null)
                {
                    if (Me.GroupInfo.IsInRaid)
                    {
                        return false;
                    }
                    else if (Me.GroupInfo.IsInParty)
                    {
                        return false;
                    }
                    else if (Me.IsInInstance)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        #endregion groupinfo

        #region CreateHealthstone
        public bool CreateNewHealthStone()
        {
                WoWItem hstone = Me.BagItems.FirstOrDefault(h => h.Entry == 5512);
                if (hstone == null 
                    && LastSpell != CreateHealthStone)
                {
                    CastSpell(CreateHealthStone, 2);
                }
            return false;
        }
        #endregion createhealthstone

        #region AddCounting
        private int addCount
        {
            get
            {
                int count = 0;
                foreach (WoWUnit u in ObjectManager.GetObjectsOfType<WoWUnit>(true, true))
                {
                    if (Me.CurrentTarget != null
                        && u.IsAlive
                        && u.Guid != Me.Guid
                        && !u.IsFriendly
                        && u.IsHostile
                        && u.Attackable
                        && !u.IsTotem
                        && !u.IsCritter
                        && !u.IsNonCombatPet
                        && (u.Location.Distance(Me.CurrentTarget.Location) <= 10 || u.Location.Distance2D(Me.CurrentTarget.Location) <= 10))
                    {
                        count++;
                    }
                }
                return count;
            }
        }
        private int PsyAddCount
        {
            get
            {
                int count = 0;
                foreach (WoWUnit u in ObjectManager.GetObjectsOfType<WoWUnit>(true, true))
                {
                    if (Me.CurrentTarget != null
                        && u.IsAlive
                        && u.Guid != Me.Guid
                        && !u.IsFriendly
                        && u.IsHostile
                        && u.Attackable
                        && !u.IsTotem
                        && !u.IsCritter
                        && !u.IsNonCombatPet
                        && u.Location.Distance(Me.CurrentTarget.Location) <= 8)
                    {
                        count++;
                    }
                }
                return count;
            }
        }
        #endregion AddCounting

        #region Movement
        public void MoveInRange(float dist)
        {
            if (Me.CurrentTarget != null)
            {
                float range = dist;
                while (Me.CurrentTarget != null
                    && StyxWoW.Me.Location.Distance(StyxWoW.Me.CurrentTarget.Location) > range)
                {
                    Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
                }
                Navigator.PlayerMover.MoveStop();
            }

        }
        public void MoveBack(WoWMovement.MovementDirection direction)
        {
            var currentPos = StyxWoW.Me.Location;
            var targetPos = StyxWoW.Me.CurrentTarget.Location;
            var gotoPos = 8;

            MoveBackTimer.Start();

            while (StyxWoW.Me.Location.Distance(targetPos) < gotoPos
                || MoveBackTimer.Elapsed.Seconds >= 2)
            {
                WoWMovement.Move(direction);
            }

            Navigator.PlayerMover.MoveStop();
            MoveBackTimer.Reset();
        }
        public void MoveToLineOfSight()
        {
            if (Me.CurrentTarget != null)
            {
                while (!Me.CurrentTarget.InLineOfSight)
                {
                    Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
                }
                Navigator.PlayerMover.MoveStop();
            }
        }
        #endregion Movement

        #region facing
        public void Facing()
        {
            if (Me.CurrentTarget != null)
            {
                Me.CurrentTarget.Face();
            }
        }
        #endregion facing

        private bool NeedClearTarget
        {
            get
            {
                if (Me.GotTarget
                    && (Me.CurrentTarget.IsDead || !Me.CurrentTarget.Attackable))
                {
                    return true;
                }
                return false;
            }
        }

        #region Trinkets
        public bool UseTrinket1()
        {
            if (Me.CurrentTarget != null
                && Me.Combat)
            {
                var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;

                 
                    if (LockerySettings.myPrefs.Trinket1 == 2
                        && IsBoss)
                    {
                        if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                        {
                            firstTrinket.Use();
                            LogMsg("Using 1st trinket", 2);
                        }
                  
                    else if (LockerySettings.myPrefs.Trinket1 == 1)
                    {
                        if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                        {
                            firstTrinket.Use();
                            LogMsg("Using 1st trinket", 2);
                        }
                    }
                }
            }
            return false;
        }
        public bool UseTrinket2()
        {
            if (Me.CurrentTarget != null
                && Me.Combat)
            {
                var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;
                 
                    if (IsBoss
                            && LockerySettings.myPrefs.Trinket2 == 2)
                    {
                        if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                        {
                            secondTrinket.Use();
                            LogMsg("Using 2nd trinket", 2);
                        }
                    }
                    else if (LockerySettings.myPrefs.Trinket2 == 1)
                    {
                        if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                        {
                            secondTrinket.Use();
                            LogMsg("Using 2nd trinket", 2);
                        }
                    }
           
            }
            return false;
        }
        public void UseEngibelt()
        {
            var engiBelt = StyxWoW.Me.Inventory.Equipped.Waist;

            if (IsBoss
                        && LockerySettings.myPrefs.UseEngiBelt)
            {
                if (engiBelt != null && CanUseEquippedItem(engiBelt))
                {
                    engiBelt.Use();
                    LogMsg("Using Engineer Belt", 2);
                }
            }
            else if (!LockerySettings.myPrefs.UseEngiBelt)
            {
                if (engiBelt != null && CanUseEquippedItem(engiBelt))
                {
                    engiBelt.Use();
                    LogMsg("Using Engineer Belt", 2);
                }
            }
        }
        public bool UseEngiGloves()
        {
            if (Me.CurrentTarget != null
                && Me.Combat)
            {
                var engiGloves = StyxWoW.Me.Inventory.Equipped.Hands;

                if (IsBoss
                    && LockerySettings.myPrefs.UseEngiGloves == 2)
                {
                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        LogMsg("Using Engineer Gloves", 2);
                    }
                }
                else if (LockerySettings.myPrefs.UseEngiGloves == 1)
                {
                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        LogMsg("Using Engineer Gloves", 2);
                    }
                }
            }
            return false;
        }
        private static bool CanUseEquippedItem(WoWItem item)
        {
            // Check for engineering tinkers!
            string itemSpell = Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0);
            if (string.IsNullOrEmpty(itemSpell))
                return false;


            return item.Usable && item.Cooldown <= 0;
        }
        #endregion Trinkets

        #region targettest
        public static void EnsureTarget()
        {
            if (StyxWoW.Me.IsInInstance &&
                TankManager.TargetingTimer.IsFinished && StyxWoW.Me.Combat && TankManager.Instance.FirstUnit != null &&
                (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget != TankManager.Instance.FirstUnit))
            {
                Logging.Write("Targeting first unit of TankTargeting");
                TankManager.Instance.FirstUnit.Target();
                TankManager.TargetingTimer.Reset();
            }

            WoWObject ctx = GatherTarget();
            if (ctx != null)
            {
                Logging.Write("Current target is not the best target. Switching to " + ctx + "!");
                ((WoWUnit)ctx).Target();
            }

            if (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget.IsDead)
            {
                ctx = GatherTarget2();
                if (ctx != null)
                {
                    Logging.Write("Currect target is invalid. Switching to " + ctx + "!");
                    ((WoWUnit)ctx).Target();
                }
            }
        }

        private static WoWObject GatherTarget2()
        {
            // If we have a RaF leader, then use its target.
            var rafLeader = RaFHelper.Leader;
            if (rafLeader != null && rafLeader.IsValid && !rafLeader.IsMe && rafLeader.Combat &&
                rafLeader.CurrentTarget != null && rafLeader.CurrentTarget.IsAlive && !Blacklist.Contains(rafLeader.CurrentTarget))
            {
                return rafLeader;
            }

            // Check bot poi.
            if (BotPoi.Current.Type == PoiType.Kill)
            {
                var unit = BotPoi.Current.AsObject as WoWUnit;

                if (unit != null && unit.IsAlive && !unit.IsMe && !Blacklist.Contains(unit))
                {
                    return unit;
                }
            }

            // Does the target list have anything in it? And is the unit in combat?
            // Make sure we only check target combat, if we're NOT in a BG. (Inside BGs, all targets are valid!!)
            var firstUnit = Targeting.Instance.FirstUnit;
            if (firstUnit != null && firstUnit.IsAlive && !firstUnit.IsMe && firstUnit.Combat &&
                !Blacklist.Contains(firstUnit))
            {
                return firstUnit;
            }

            // Cache this query, since we'll be using it for 2 checks. No need to re-query it.
            var agroMob =
                ObjectManager.GetObjectsOfType<WoWUnit>(false, false).
                    Where(p => !Blacklist.Contains(p) && p.IsHostile && !p.IsOnTransport && !p.IsDead &&
                                !p.Mounted && p.DistanceSqr <= 70 * 70 && p.Combat).
                    OrderBy(u => u.DistanceSqr).
                    FirstOrDefault();

            if (agroMob != null)
            {
                // Return the closest one to us
                return agroMob;
            }

            // And there's nothing left, so just return null, kthx.
            return null;
        }

        private static WoWObject GatherTarget()
        {
            // No target switching for tanks. They check for their own stuff above.
            if (StyxWoW.Me.IsInInstance)
                return null;
            // Go below if current target is null or dead. We have other checks to deal with that
            if (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget.IsDead)
                return null;
            // If the current target is in combat or has aggro towards us, it should be a valid target.
            if (StyxWoW.Me.CurrentTarget != null && (StyxWoW.Me.CurrentTarget.Combat || StyxWoW.Me.CurrentTarget.Aggro))
                return null;
            if (BotPoi.Current.Type == PoiType.Kill)
            {
                var obj = BotPoi.Current.AsObject;

                if (obj != null)
                {
                    if (StyxWoW.Me.CurrentTarget != obj)
                        return obj;
                }
            }
            // Make sure we have the proper target from Targeting. 
            // The Botbase should give us the best target in targeting.
            var firstUnit = Targeting.Instance.FirstUnit;

            if (firstUnit != null)
            {
                if (StyxWoW.Me.CurrentTarget != firstUnit)
                    return firstUnit;
            }
            return null;
        }
        public float MeleeRange
        {
            get
            {
                if (StyxWoW.Me.CurrentTargetGuid == 0)
                    return 0f;

                if (StyxWoW.Me.CurrentTarget.IsPlayer)
                    return 3.5f;

                return Math.Max(5f, StyxWoW.Me.CombatReach + 1.3333334f + StyxWoW.Me.CurrentTarget.CombatReach);
            }
        }
        #endregion


        #region logs
        public static void LogMsg(string msg, int kleurtje)
        {
            Color kleur = Colors.Yellow;
            switch (kleurtje)
            {
                case 0:
                    kleur = Colors.Orange;
                    break;
                case 1:
                    kleur = Colors.PaleGreen;
                    break;
                case 2:
                    kleur = Colors.BlanchedAlmond;
                    break;
                case 3:
                    kleur = Colors.Yellow;
                    break;
                case 4:
                    kleur = Colors.Red;
                    break;
                case 5:
                    kleur = Colors.Crimson;
                    break;
                case 6:
                    kleur = Colors.LightBlue;
                    break;
                case 7:
                    kleur = Colors.LightBlue;
                    break;
            }
            Logging.Write(kleur, msg);
        }
        #endregion logs

        #region Kind of target
        public bool IsBoss
        {
            get
            {
                if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.WorldBoss)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && target.IsBoss(Me.CurrentTarget))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.MaxHealth >= (65 * 1000000))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.RareElite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * LockerySettings.myPrefs.ElitesHealth)
                    && !Me.GroupInfo.IsInParty
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * LockerySettings.myPrefs.ElitesHealth)
                    && !Me.GroupInfo.IsInParty
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Rare
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * LockerySettings.myPrefs.ElitesHealth)
                    && !Me.GroupInfo.IsInParty
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.Name.Contains("Training Dummy"))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsPlayer
                    && !Me.CurrentTarget.IsFriendly)
                {
                    return true;
                }
                return false;
            }
        }

        #endregion Kind of Target


        #region spell cooldwon
        public static TimeSpan GetSpellCooldown(string spell)
        {
            SpellFindResults results;
            if (SpellManager.FindSpell(spell, out results))
            {
                if (results.Override != null)
                    return results.Override.CooldownTimeLeft;
                return results.Original.CooldownTimeLeft;
            }


            return TimeSpan.MaxValue;
        }
        #endregion spell cooldown

        #region MyAuraTimeLeft

        public double MyAuraTimeLeft(string auraName, WoWUnit u)
        {
            using (StyxWoW.Memory.AcquireFrame())
            {
                if (u == null || !u.IsValid || !u.IsAlive)
                    return 0;

                WoWAura aura = u.GetAllAuras().FirstOrDefault(a => a.Name == auraName && a.CreatorGuid == Me.Guid);

                if (aura == null)
                {
                    return 0;
                }
                return aura.TimeLeft.TotalMilliseconds;
            }
        }

        public double MyAuraTimeLeft(int auraID, WoWUnit u)
        {
            using (StyxWoW.Memory.AcquireFrame())
            {
                if (u == null || !u.IsValid || !u.IsAlive)
                    return 0;

                WoWAura aura = u.GetAllAuras().FirstOrDefault(a => a.SpellId == auraID && a.CreatorGuid == Me.Guid);

                if (aura == null)
                {
                    return 0;
                }
                return aura.TimeLeft.TotalMilliseconds;
            }
        }

        #endregion

        #region MultiDotting
        public void MultiDotImmolate()
        {  

            int MaxTeller = 0;

            if (addCount >= LockerySettings.myPrefs.AutoDotImmolate)
            {
                MaxTeller = LockerySettings.myPrefs.AutoDotImmolate;
            }
            if (addCount <= LockerySettings.myPrefs.AutoDotImmolate)
            {
                MaxTeller = addCount;
            }
            int teller = 0;
         
            IEnumerable<WoWUnit> units =
                   ObjectManager.GetObjectsOfType<WoWUnit>(true, true).Where(u =>
                        !u.IsPlayer
                        && (u.IsTargetingMeOrPet
                        || u.IsTargetingMyPartyMember
                        || u.IsTargetingMyRaidMember)
                        && u.IsAlive
                        && u.Guid != Me.Guid
                        && !u.IsFriendly
                        && !u.IsPet
                        && u.Attackable
                        && !u.IsTotem
                        && !u.IsCritter
                        && !u.IsNonCombatPet
                        && u.InLineOfSight
                        && !u.HasAura(Immolate)
                        && IsInRange(u, 35));
            
            foreach (WoWUnit adds in units)
            { 
                adds.Target();

                if (teller == 0)
                {
                    WoWUnit myPrimaryTarget = adds;
                }
                if (UseSkill(Immolate))
                    {
                        CastSpell(Immolate, 7);
                        teller++;
                    }
                    LogMsg("Multidot " + adds.Name, 0);
                    StyxWoW.SleepForLagDuration();

                if (teller == MaxTeller)
                {
                    if (myPrimaryTarget.IsAlive)
                    {
                        myPrimaryTarget.Target();
                        LogMsg("Back to my 1st target " + adds.Name, 0);
                    }
                    else if (myPrimaryTarget.IsDead)
                    {
                        LogMsg("New target " + adds.Name, 0);
                    }
                    Dotting = "done";
                    dotTimer.Start();
                    break;
                }

            }

        }
        #endregion

        #region Rain of Fire
        public bool Firerain()
        {
            if (!Me.IsChanneling)
            {
                Lua.DoString("CastSpellByName('Rain of Fire');");
                {
                    SpellManager.ClickRemoteLocation(StyxWoW.Me.CurrentTarget.Location);
                    LogMsg(">> Rain of Fire <<", 3);
                }
                return true;
            }
            return false;
        }
        #endregion Rain of Fire
        #region IsInRange

        private static bool IsInRange(WoWUnit target, int range)
        {
            if (target == null)
            {
                return false;
            }

            if (target.DistanceSqr < range * range || SafeTarget.Contains(target.Entry))
            {
                return true;
            }
            return false;
        }
        #endregion IsInRange

        public bool IsEnemy(WoWUnit target)
        {
            if (target == null)
            {
                return false;
            }

            if (!target.IsFriendly || target.Name.Contains("Dummy") && target.IsWithinMeleeRange)
            {
                return true;
            }
            return false;
        }
        #region class
        public bool EnemySpec()
        {
            var target = WoWSpec.MageFire;
            if (target == null)
            {
                return false;
            }
            if (target == WoWSpec.PaladinHoly
                || target == WoWSpec.PaladinRetribution
                || target == WoWSpec.PaladinProtection)
            {
                return true;
            }
            if (target == WoWSpec.PriestShadow
                || target == WoWSpec.PriestHoly)
            {
                return true;
            }
            if (target == WoWSpec.WarlockDemonology)
            {
                return true;
            }
            return false;
        }
        #endregion class

        #region ValidUnit

        public bool ValidUnit(WoWUnit myTarget)
        {
            if (myTarget == null
                || !myTarget.IsValid
                || !myTarget.Attackable
                || !myTarget.IsAlive
                || !myTarget.CanSelect
                || myTarget.IsCritter
                && (myTarget.CurrentTarget == null
                || myTarget.CurrentTarget != null
                && myTarget.CurrentTarget != Me)
                || myTarget.IsNonCombatPet
                || Blacklist.Contains(myTarget.Guid))
            {
                return false;
            }
            return true;
        }
        private static readonly HashSet<uint> SafeTarget = new HashSet<uint>
                                                               {
                                                                   60410, //Elegon
                                                                   60776, //Empyreal Focus
                                                                   60793, //Celestial Protector
                                                                   60913, //Energy Charge
                                                               };

        #endregion

        #region UpdateMyLatency
        public DateTime LastUpdateMyLatency;

        public static double MyLatency;

        public void UpdateMyLatency()
        {
            MyLatency = (StyxWoW.WoWClient.Latency);

            if (MyLatency > 400)
            {
                MyLatency = 400;
            }
        }

        #endregion


        /*public void EnsureHavoc()
        {
            if (gotTarget
                && SpellManager.HasSpell(Havoc)
                && !spellOnCooldown(Havoc)
                && LastSpell != Havoc)
            {
                var myCurrenttarget = Me.CurrentTarget;
                HavocManager.HavocInstance.FirstUnit.Target();
                if (SpellManager.CanCast(Havoc))
                {
                    SpellManager.Cast(Havoc);
                    LogMsg(Havoc, 6);
                    LastSpell = Havoc;
                    myCurrenttarget.Target();
                }
            }

        }
        #region havoc targets

       
        
            public static readonly WaitTimer HavocTimer = new WaitTimer(TimeSpan.FromSeconds(1));

            static HavocManager()
            {
                HavocInstance = new HavocManager { NeedToHavoc = new List<WoWUnit>() };
            }

            public new static HavocManager HavocInstance { get; set; }
            public List<WoWUnit> NeedToHavoc { get; private set; }

            protected override List<WoWObject> GetInitialObjectList()
            {
                return ObjectManager.GetObjectsOfType<WoWUnit>(false, false).Cast<WoWObject>().ToList();
            }

            protected override void RemoveHavocFilter(List<WoWObject> units)
            {
                for (int i = units.Count - 1; i >= 0; i--)
                {
                    if (!units[i].IsValid)
                    {
                        units.RemoveAt(i);
                        continue;
                    }

                    WoWUnit u = units[i].ToUnit();

                    if (u.IsFriendly || u.IsDead || u.IsPet || !u.Combat)
                    {
                        units.RemoveAt(i);
                        continue;
                    }

                    if (u.DistanceSqr > 40 * 40)
                    {
                        units.RemoveAt(i);
                        continue;
                    }

                    WoWUnit tar = u.CurrentTarget;
                    if (!tar.IsPlayer || !tar.IsHostile)
                        continue;

                    units.RemoveAt(i);
                }
            }

            protected override void DefaultIncludeTargetsFilter(List<WoWObject> incomingUnits,
                                                                HashSet<WoWObject> outgoingUnits)
            {
                foreach (WoWObject i in incomingUnits)
                {
                    var unit = i as WoWUnit;

                    outgoingUnits.Add(i);
                }
            }

            protected override void DefaultTargetWeight(List<TargetPriority> units)
            {
                NeedToHavoc.Clear();
                List<WoWPlayer> members = StyxWoW.Me.GroupInfo.IsInRaid ? StyxWoW.Me.RaidMembers : StyxWoW.Me.PartyMembers;
                foreach (TargetPriority p in units)
                {
                    WoWUnit u = p.Object.ToUnit(); 
                    if (!u.Fleeing && u != Me.CurrentTarget)
                    {
                        NeedToHavoc.Add(u);
                    }
                }
            }

        #endregion havoc targets
         * */

         

    }
}

